import { message } from "antd";
import { ReactNode, isValidElement } from "react";
import { ArgsProps } from "antd/es/message";
import { NoticeType } from "antd/es/message/interface";

export { default as storage } from "./storage";

/**
 * 检测元素所属类型
 * Object.prototype.toString.call(*)的可能结果如下所示：
 * @example null             [object Null]
 * @example undefined        [object Undefined]
 * @example Symbol());       [object Symbol]
 * @example true             [object Boolean]
 * @example ''               [object String]
 * @example 1                [object Number]
 * @example []               [object Array]
 * @example {}               [object Object]
 * @example new Date()       [object Date]
 * @example new Function()   [object Function]
 * @example new RegExp()     [object RegExp]
 * @example new Error()      [object Error]
 * @example document         [object HTMLDocument]
 * @example window           [object global] window 是全局对象 global 的引用
 * @param {*} ele 待检测的对象、字符串、数组等
 * @returns {String} 元素类型（String、Number、Boolean、Symbol、Undefined、Null、Function、Date、Array、Object、Regexp、Error、HtmlDocument、Global）
 */
export function typeOf(ele: any) {
  const endStr = Object.prototype.toString.call(ele);
  const type = endStr.split(" ")[1].slice(0, -1);
  return type;
}

/**
 * 获取 ReactNode 的文本字符串
 * @param node ReactNode Rect的节点
 */
export function getTextFromReactNode(node: ReactNode): string {
  if (!node) return "";
  if (["string", "number"].includes(typeof node)) return String(node);
  if (Array.isArray(node)) return node.map(getTextFromReactNode).join("");
  if (typeof node === "object" && node !== null) {
    if (node?.props?.children) return getTextFromReactNode(node.props.children); // 处理有可能有子节点的情况
  }
  return "";
}

/**
 * 展示message提示信息
 * @param hint string, MessageParams 提示内容
 * @description 默认展示成功通知
 */
export function showMessage(
  hint: ReactNode | ArgsProps,
  type: NoticeType = "success",
  others?: ArgsProps
) {
  if (!hint) return;
  let hintStr: string = "";
  if (typeof hint === "string") {
    hintStr = hint;
  } else if (isValidElement(hint)) {
    hintStr = getTextFromReactNode(hint);
  } else if (typeOf(hint) === "Object") {
    hintStr = getTextFromReactNode((hint as ArgsProps).content);
  } else {
    throw new Error(`暂未处理此种类型：${typeOf(hint)}`);
  }
  const speed = 7; //速度：9字/秒
  let duration = hintStr.length / speed;
  if (duration < 1.5) duration = 1.5;
  const isObj = typeOf(hint) === "Object";
  const cfg = isObj
    ? Object.assign({ duration }, hint as ArgsProps)
    : { content: hint, duration };
  message[type](Object.assign(cfg, others));
}

/**
 * 对象数组排序（默认order）
 * @param arr {}[] 要排序的数组
 * @param key string 排序依据的对象属性键名
 * @param type string 排序方式 asc 升序 desc 降序
 */
export function sortObjArrByKey(
  arr: CommonObj[] = [],
  key = "order",
  type = "asc"
): CommonObj[] {
  arr.sort((a: CommonObj, b: CommonObj) => {
    if (type === "asc") {
      return a[key] - b[key];
    } else if (type === "desc") {
      return b[key] - a[key];
    } else if (type === "random") {
      return Math.random() - 0.5;
    }
  });
  return arr;
}
